package com.example.mcu_up.serial;




import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.nio.ByteBuffer;



import android.util.Log;

public class Mcu_Pack  implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1000L;
	private byte header;
	private byte type;//类型
	private static int len=0;//长度
	private byte[] data;//数据
	private int check;
	private byte end;
	

	public byte getEnd() {
		return end;
	}

	public void setEnd(byte end) {
		this.end = end;
	}

	public byte getHeader() {
		return header;
	}

	public void setHeader(byte header) {
		this.header = header;
	}

	
	public int getCheck() {
		return check;
	}

	public void setCheck(int check) {
		this.check = check;
	}

	public byte getType() {
		return type;
	}

	public void setType(byte type) {
		this.type = type;
	}

	public int getLen() {
		return len;
	}

	public void setLen(int len) {
		this.len = len;
	}

	public byte[] getData() {
		return data;
	}

	public void setData(byte[] data) {
		this.data = data;
	}

	  //byte 数组与 int 的相互转换  
    public static int byteArrayToInt(byte[] b) {  
        return   b[3] & 0xFF |  
                (b[2] & 0xFF) << 8 |  
                (b[1] & 0xFF) << 16 |  
                (b[0] & 0xFF) << 24;  
    }  
  
    public static byte[] intToByteArray(int a) {  
        return new byte[] {  
            (byte) ((a >> 24) & 0xFF),  
            (byte) ((a >> 16) & 0xFF),     
            (byte) ((a >> 8) & 0xFF),     
            (byte) (a & 0xFF)  
        };  
    }  
	/** 
     * 将int数值转换为占四个字节的byte数组，本方法适用于(高位在前，低位在后)的顺序。  和bytesToInt2（）配套使用
     */  
	public static byte[] intToBytes_M(int value) 
	{ 
		byte[] src = new byte[2];
		
		src[0] = (byte) ((value>>8)&0xFF);
		src[1] = (byte) (value & 0xFF);		
		return src;
	}
	
	
	 /** 
     * byte数组中取int数值，本方法适用于(高位在前，低位在后)的顺序。和intToBytes2（）配套使用
     */
	
	
	public static int bytesToInt_M(byte[] src, int offset) {
		int value;	
		value = (int) 
				((src[offset] & 0xFF)<<8)
				|(src[offset+1] & 0xFF);
		return value;
	}
	
	
	
	
	/** 
     * 将int数值转换为占四个字节的byte数组，本方法适用于(低位在前，高位在后)的顺序。  和bytesToInt2（）配套使用
     */  
	/*public static byte[] intToBytes_L(int value) 
	{ 
	    byte[] abyte0 = new byte[2];

        abyte0[0] = (byte) (0xff & value);

   
        abyte0[1] = (byte) (0xff & (value >> 8));

        return abyte0;

	}*/
	 /** 
     * 将int数值转换为占四个字节的byte数组，本方法适用于(低位在前，高位在后)的顺序。 和bytesToInt（）配套使用
     * @param value 
     *            要转换的int值
     * @return byte数组
     */  
	public static byte[] intToBytes_L( int value ) 
	{ 
		byte[] src = new byte[2];
	
		src[1] =  (byte) ((value>>8) & 0xFF);  
		src[0] =  (byte) (value & 0xFF);				
		return src; 
	}
	
	 /** 
     * byte数组中取int数值，本方法适用于(低位在前，高位在后)的顺序。和intToBytes2（）配套使用
     */
	
	
	/*public static int bytesToInt_L(byte[] src) {
	     int addr =  (0xFF&src[0]);

	        addr |= (0xFF&(src[1]<<8));
		
		return addr;
	}*/
	
	
	public static int bytesToInt_L(byte[] res) {
        // res = InversionByte(res);
        // 一个byte数据左移24位变成0x??000000，再右移8位变成0x00??0000
  	Log.e("getpack1","第一个数"+String.valueOf(res[0]&0xff));
        
    	
    	Log.e("getpack1","第二个数"+String.valueOf(res[1]));
    	
        
    	int targets = (res[0] & 0xff) | ((res[1] << 8) & 0xff00);
        
  
    	
        return targets;
    }

	
	public static int bytesToInt3(byte[] src, int offset) {
		int value;	
		value = (int) ((src[offset] & 0xFF)<<16)
				|((src[offset+1] & 0xFF)<<8)
				|(src[offset+2] & 0xFF);
		return value;
	}
	
	
	/**
	  *将32位的int值放到4字节的里
	  * @param num
	  * @return
	  */
	public static byte[] int2byteArray(int num) {
	   byte[] result = new byte[4];
	   result[0] = (byte)(num >>> 24);//取最高8位放到0下标
	   result[1] = (byte)(num >>> 16);//取次高8为放到1下标
	   result[2] = (byte)(num >>> 8); //取次低8位放到2下标
	   result[3] = (byte)(num );      //取最低8位放到3下标
	   return result;
	}

	/**
	  * 将4字节的byte数组转成一个int值
	  * @param b
	  * @return
	  */
	public static int byteArray2int(byte[] b){
	    byte[] a = new byte[4];
	    int i = a.length - 1,j = b.length - 1;
	    for (; i >= 0; i--,j--) {//从b的尾部(即int值的低位)开始copy数据
	        if(j >= 0)
	            a[i] = b[j];
	        else
	            a[i] = 0;//如果b.length不足4,则将高位补0
	  }
	    int v0 = (a[0] & 0xff) << 24;//&0xff将byte值无差异转成int,避免Java自动类型提升后,会保留高位的符号位
	    int v1 = (a[1] & 0xff) << 16;
	    int v2 = (a[2] & 0xff) << 8;
	    int v3 = (a[3] & 0xff) ;
	    return v0 + v1 + v2 + v3;
	}
	
	
	/*
	 * byte为一位数的时候用
	 */
	public static int readOne(byte[] b){
		int a=-1;
		DataInputStream dis=new DataInputStream(new ByteArrayInputStream(b));
		try {
			 a=dis.readByte();
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		return a;	
	}
	/*
	 * 1,2时候用
	 */
	public static int[] readOneTwo(byte[] b){
		int[]  a=new int[2];
		DataInputStream dis=new DataInputStream(new ByteArrayInputStream(b));
		
		try {
			a[0]=dis.readByte();
			a[1]=dis.readShort();
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		return a;	
	}
	
	/*
	 * 2,2时候用
	 */
	public static int[] readTwoTwo(byte[] b){
		int[]  a=new int[2];
		DataInputStream dis=new DataInputStream(new ByteArrayInputStream(b));
		byte[] res=new byte[4];
		try {
			
			res[0]=dis.readByte();
			res[1]=dis.readByte();
			res[2]=dis.readByte();
			res[3]=dis.readByte();
			
			a[0] = (res[0] & 0xff) | ((res[1] << 8) & 0xff00);
			a[1]=(res[2] & 0xff) | ((res[3] << 8) & 0xff00);
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		return a;	
	}
	/*
	 * 1,2,2时候用
	 */
	public static int[] readOneTwoTwo(byte[] b){
		int[]  a=new int[3];
		DataInputStream dis=new DataInputStream(new ByteArrayInputStream(b));
		try {
			a[0]=dis.readByte();
			a[1]=dis.readShort();
			a[2]=dis.readShort();
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		return a;	
	}
	
	
	/*
	 * 4,1,3时候用
	 */
	public static int[] readFourOneThree(byte[] b){
		int[]  a=new int[3];
		byte[]  c=new byte[3];
		DataInputStream dis=new DataInputStream(new ByteArrayInputStream(b));
		try {
			a[0]=dis.readInt();
			a[1]=dis.readByte();
			c[0]=dis.readByte();
			c[1]=dis.readByte();
			c[2]=dis.readByte();
			a[2]=Mcu_Pack.bytesToInt3(c, 0);
			
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		return a;	
	}
	
	/*
	 * 应答码时候用
	 */
	public static String answer(byte[] b){
		String a=null;
		DataInputStream dis=new DataInputStream(new ByteArrayInputStream(b));
		try {
			a=dis.readByte()==1?"OK":"Error";
		} catch (IOException e) {
			
			e.printStackTrace();
		}
		return a;	
	}
	
	
	
	public int readShort(DataInputStream is){
		byte[] b=new byte[2];
		try {
			b[0]=is.readByte();
			b[1]=is.readByte();
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	
		return bytesToInt_L(b);
	}

	
	
	
	
	
	
    /*
	 * 接收包，如果type类型 为0x00就是应答包，如果不是就是正常 的包
	 */
	
	public  Mcu_Pack  getPack(InputStream is) throws IOException, BadPackageException {

		
		Mcu_Pack p=new Mcu_Pack();
		ByteArrayOutputStream outputStream=new ByteArrayOutputStream();
		DataInputStream dis = new DataInputStream(is);
		header = dis.readByte();
		
	    if (header != (byte) 0x01) {
	    	Log.i("myheaderis", String.valueOf(header));
			throw new BadPackageException("wrong synchronize header."+header);
		}
	    
       type = dis.readByte();
	   if(!(type==0x00||type==0x02||type==0x03||type==0x04||type==0x05||type==0x06||type==0x07||type==0x08||type==0x09||type==0x0A||type==0x0c||type==0x0D||type==0x0f)){
	    	throw new BadPackageException("wrong synchronize type."+type);
	    }
	   
	   
		p.setType(type);
		len = readShort(dis);
		p.setLen(len);
		
			int remaining = len;
			byte[] buf = new byte[1024];
			while (remaining > 0) {
				
				int c = dis.read(buf, 0, remaining > 1024 ? 1024 : remaining);
				outputStream.write(buf, 0, c);
				remaining -= c;
			}
			p.setData(outputStream.toByteArray());
		
		
		check=readShort(dis);
		Log.e("getpack1",String.valueOf(check));
		p.setCheck(check);
		end=dis.readByte();
		p.setEnd(end);
		
			return p;
	}
	

	
	/*
	 *
	 */
	public byte[] tobytes(){
		header=(byte)0x01;
	    ByteBuffer b=null;
	    if(getData()!=null&&getData().length>0)
	    	len=getData().length;
	    else
	    	len=0;
	    b=ByteBuffer.allocate(len+7);
        b.put(header);//头1
   	    b.put(type);//类型1
	    b.put(intToBytes_L(len));//长度2
	    if(len!=0){
	       b.put(getData());
	    }
	   	  int	 check= CRC16.CyBtldr_ComputeChecksum(b.array(),b.array().length-3);		
	    b.put(intToBytes_L(check));//校验码
		b.put((byte) 0x17);
		 return b.array();	 
		 
	}
	
	
	public static String byteToString(byte[] b){
		StringBuffer buffer=new StringBuffer(b.length);
		for(int i=0;i<b.length;i++){
			 String strHex = Integer.toHexString(b[i]).toUpperCase();
			 if(strHex.length()>3){
				 buffer.append(strHex.substring(6)+" ");
			 }else if(strHex.length()<2){
				 buffer.append("0" + strHex+" ");
				 
			 }else{		 
				 buffer.append(strHex+" ");
			 }
		}
		return buffer.toString();
		
		
	}
	
}

